package com.ruoyi.web.controller.recipe;

import java.util.*;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.recipe.domain.RecipeCategory;
import com.ruoyi.recipe.domain.RecipeCategoryDish;
import com.ruoyi.recipe.service.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.recipe.domain.RecipeDish;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 食谱Controller
 * 
 * @author ruoyi
 * @date 2024-11-22
 */
@Controller
@RequestMapping("/recipe/dish")
public class RecipeDishController extends BaseController {
    private String prefix = "recipe/dish";

    @Autowired
    private IRecipeDishService recipeDishService;

    @Autowired
    private IRecipeCategoryService recipeCategoryService;

    @Autowired
    private IRecipeCategoryDishService recipeCategoryDishService;

    @Autowired
    private IRecipeDishItemService recipeDishItemService;

    @Autowired
    private IRecipeDishStepService recipeDishStepService;

    @Autowired
    private IRecipeDishMealService recipeDishMealService;

    @RequiresPermissions("recipe:dish:view")
    @GetMapping()
    public String dish() {
        return prefix + "/dish";
    }

    /**
     * 查询食谱列表
     */
    @RequiresPermissions("recipe:dish:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(RecipeDish recipeDish) {
        startPage();
        List<RecipeDish> list = recipeDishService.selectRecipeDishList(recipeDish);
        return getDataTable(list);
    }

    /**
     * 导出食谱列表
     */
    @RequiresPermissions("recipe:dish:export")
    @Log(title = "食谱", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(RecipeDish recipeDish) {
        List<RecipeDish> list = recipeDishService.selectRecipeDishList(recipeDish);
        ExcelUtil<RecipeDish> util = new ExcelUtil<RecipeDish>(RecipeDish.class);
        return util.exportExcel(list, "食谱数据");
    }

    /**
     * 新增食谱
     */
    @GetMapping("/add")
    public String add(ModelMap mmap) {
        mmap.put("categoryList", recipeCategoryService.selectCategoryAll());
        return prefix + "/add";
    }

    /**
     * 新增保存食谱
     */
    @RequiresPermissions("recipe:dish:add")
    @Log(title = "食谱", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(RecipeDish recipeDish) {
        return toAjax(recipeDishService.insertRecipeDish(recipeDish));
    }

    /**
     * 修改食谱
     */
    @RequiresPermissions("recipe:dish:edit")
    @GetMapping("/edit/{dishId}")
    public String edit(@PathVariable("dishId") Long dishId, ModelMap mmap) {
        RecipeDish recipeDish = recipeDishService.selectRecipeDishByDishId(dishId);
        mmap.put("recipeDish", recipeDish);
        mmap.put("categoryList", recipeCategoryService.selectCategoryAll());
        return prefix + "/edit";
    }

    /**
     * 修改保存食谱
     */
    @RequiresPermissions("recipe:dish:edit")
    @Log(title = "食谱", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(RecipeDish recipeDish) {
        return toAjax(recipeDishService.updateRecipeDish(recipeDish));
    }

    /**
     * 删除食谱
     */
    @RequiresPermissions("recipe:dish:remove")
    @Log(title = "食谱", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult remove(String ids) throws Exception {
        // ids转数组
        String[] dishIds = ids.split(",");

        // 删除菜品材料
        recipeDishItemService.deleteRecipeDishItemByDishIds(dishIds);

        // 删除菜品步骤
        recipeDishStepService.deleteRecipeDishStepByDishIds(dishIds);

        // 删除婴儿辅食
        recipeDishMealService.deleteRecipeDishMealByDishIds(dishIds);

        // 删除菜品分类关联表
        recipeCategoryDishService.deleteRecipeCategoryDishByDishIds(dishIds);

        // 删除菜品
        return toAjax(recipeDishService.deleteRecipeDishByDishIds(ids));
    }

    /**
     * 导入模板下载
     */
    @GetMapping("/importTmpl")
    @ResponseBody
    public AjaxResult importTmpl() {
        ExcelUtil<RecipeDish> util = new ExcelUtil<RecipeDish>(RecipeDish.class);
        return util.importTemplateExcel("菜品导入模板");
    }

    /**
     * 导入数据
     */
    @PostMapping("/importData")
    @ResponseBody
    public AjaxResult importData(MultipartFile file, boolean updateSupport) {
        try {
            ExcelUtil<RecipeDish> util = new ExcelUtil<RecipeDish>(RecipeDish.class);
            List<RecipeDish> list = util.importExcel(file.getInputStream());
            String message = importDish(list, updateSupport);
            return AjaxResult.success(message);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public String importDish(List<RecipeDish> list, Boolean isUpdateSupport) throws Exception {
        if (StringUtils.isNull(list) || list.size() == 0) {
            throw new Exception("导入菜品数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        List<RecipeCategory> categoryList = new ArrayList<>();

        List<RecipeCategory> categoryTmpList = recipeCategoryService.selectCategoryAll();
        // 通过categoryTmpList获取最大的categorySort
        int maxCategorySort = 1;
        if (categoryTmpList != null && categoryTmpList.size() > 0) {
            for (RecipeCategory category : categoryTmpList) {
                if (category.getCategorySort() > maxCategorySort) {
                    maxCategorySort = category.getCategorySort();
                }
            }
        }
        // categoryName categoryId键值对
        Map<String, Long> categoryTmpMap = new HashMap<>();
        for (RecipeCategory category : categoryTmpList) {
            categoryTmpMap.put(category.getCategoryName(), category.getCategoryId());
        }

        // 处理食谱类别
        for (RecipeDish item : list) {
            String newValue = StringUtils.replace(item.getDishTitle(), "，", ",");
            List<String> dishTitleList = StringUtils.str2List(newValue, ",", true, true);
            if (dishTitleList != null && dishTitleList.size() > 0) {
                for (String dishTitle : dishTitleList) {
                    if (StringUtils.isEmpty(dishTitle)) continue;

                    if (StringUtils.isNull(categoryTmpMap.get(dishTitle))) {
                        RecipeCategory category = new RecipeCategory();
                        category.setCategoryName(dishTitle);
                        category.setCategorySort(++maxCategorySort);
                        category.setVisible("1");
                        category.setStatus("0");
                        categoryList.add(category);
                    }
                }
            }
        }
        if (categoryList.size() > 0) {
            int rt = recipeCategoryService.batchInsertCategory(categoryList);
            if (rt < categoryList.size()) {
                throw new Exception("很抱歉，导入失败：食谱类别保存失败！");
            }
            successMsg.append("成功导入食谱类别数据 " + categoryList.size() + " 条！");
        }

        // 开始处理菜品
        List<RecipeCategory> categoryFullList = recipeCategoryService.selectCategoryAll();
        // categoryName categoryId键值对
        Map<String, Long> categoryMap = new HashMap<>();
        for (RecipeCategory category : categoryFullList) {
            categoryMap.put(category.getCategoryName(), category.getCategoryId());
        }

        int maxDishSort = recipeDishService.selectMaxDishSort(new RecipeDish());
        if (maxDishSort < 1) maxDishSort = 1;

        List<RecipeCategoryDish> categoryDishList = new ArrayList<>();
        Iterator<RecipeDish> iterator = list.iterator();
        while (iterator.hasNext()) {
            RecipeDish item = iterator.next();

            if (failureNum >= 10) {
                break;
            }

            if (StringUtils.isEmpty(item.getDishName())) {
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、" + item.getDishName() + " 导入失败：" + "菜品名称不能为空");

                continue;
            }

            // 处理菜品和类别关系
            if (StringUtils.isNotEmpty(item.getDishTitle())) {
                String newValue = StringUtils.replace(item.getDishTitle(), "，", ",");
                List<String> dishTitleList = StringUtils.str2List(newValue, ",", true, true);
                for (String dishTitle : dishTitleList) {
                    if (StringUtils.isEmpty(dishTitle)) continue;
                    if (StringUtils.isNull(categoryMap.get(dishTitle))) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、" + item.getDishName() + " 导入失败：" + "类别 " + dishTitle + " 不存在");

                        continue;
                    }
                    RecipeCategoryDish categoryDish = new RecipeCategoryDish();
                    categoryDish.setCategoryId(categoryMap.get(dishTitle));
                    categoryDish.setDishName(item.getDishName());
                    categoryDishList.add(categoryDish);
                }
            }

            item.setDishSort(maxDishSort++);
            item.setCreateTime(DateUtils.getNowDate());
            item.setUpdateTime(DateUtils.getNowDate());
            item.setStatus("0");
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！请修改文件后重试：");
            throw new Exception(failureMsg.toString());
        }

        int rows = 0;
        if (isUpdateSupport) {
            rows = recipeDishService.batchInsertOrUpdateRecipeDish(list);
        } else {
            rows = recipeDishService.batchInsertRecipeDish(list);
        }

        if (rows < list.size()) {
            failureMsg.insert(0, "很抱歉，导入失败：保存菜品数据失败");
            throw new Exception(failureMsg.toString());
        } else {
            successMsg.insert(0, "成功导入菜品数据 " + list.size() + " 条！");
        }

        //查询菜品
        List<RecipeDish> dishInDBList = recipeDishService.selectRecipeDishList(new RecipeDish());
        Map<String, Long> dishMap = new HashMap<>();
        for (RecipeDish dish : dishInDBList) {
            dishMap.put(dish.getDishName(), dish.getDishId());
        }

        //保存菜品和类别的关系
        for (RecipeCategoryDish item : categoryDishList) {
            item.setDishId(dishMap.get(item.getDishName()));
        }
        rows = recipeCategoryDishService.batchInsertRecipeCategoryDish(categoryDishList);
        if (rows <= 0) {
            failureMsg.insert(0, "很抱歉，导入失败：菜品和类型的关系保存失败！");
            throw new Exception(failureMsg.toString());
        }
        successMsg.append("成功导入菜品和类型的关系数据 " + categoryDishList.size() + " 条！");

        return successMsg.toString();
    }

    /**
     * 材料管理
     */
    @RequiresPermissions("recipe:dish:edit")
    @GetMapping("/itemManage/{dishId}")
    public String itemManage(@PathVariable("dishId") Long dishId, ModelMap mmap) {
        RecipeDish recipeDish = recipeDishService.selectRecipeDishByDishId(dishId);
        mmap.put("recipeDish", recipeDish);
        return prefix + "/item";
    }

    /**
     * 步骤管理
     */
    @RequiresPermissions("recipe:dish:edit")
    @GetMapping("/stepManage/{dishId}")
    public String stepManage(@PathVariable("dishId") Long dishId, ModelMap mmap) {
        RecipeDish recipeDish = recipeDishService.selectRecipeDishByDishId(dishId);
        mmap.put("recipeDish", recipeDish);
        return prefix + "/step";
    }

    /**
     * 辅食管理
     */
    @RequiresPermissions("recipe:dish:edit")
    @GetMapping("/mealManage/{dishId}")
    public String mealManage(@PathVariable("dishId") Long dishId, ModelMap mmap) {
        RecipeDish recipeDish = recipeDishService.selectRecipeDishByDishId(dishId);
        mmap.put("recipeDish", recipeDish);
        return prefix + "/meal";
    }

}
